package betandregret;
import java.util.Calendar;
import java.util.LinkedList;

import betandregret.exceptions.RegretException;
import betandregret.interfaces.IBetAndRegret.Systemereignis;

public class Spielverwaltung {

	private SpielCollection spiele;

	private Wettverwaltung wv;

	private SportartCollection sportarten;

	private LinkedList<Endergebnis> endergebnisse;

	private TeamCollection teams;
	
	
	/**
	 *constructor
	 *!Achtung! Spielverwaltung kennt noch nicht die Wettverwaltung, muss noch mit setter gesetzt werden 
	 * @param datum
	 */
	public Spielverwaltung() {
		this.spiele = new SpielCollection();
		this.sportarten = new SportartCollection();
		this.endergebnisse = new LinkedList<Endergebnis>();
		this.teams = new TeamCollection();
	}
	
	
	public void setWettverwaltung(Wettverwaltung wv){
		this.wv = wv;
	}

	/**
	 * Diese Methode erstellt ein neues Spiel zwischen dem Team mit der ID
	 * team1ID und dem Team mit der ID team2ID zur Startzeit mit dem uebergebenen
	 * Mindesteinsatz. Dies funktioniert nur, wenn beide Teams in der gleichen
	 * Sportart registriert sind und in der Zeit des Spiels in der Zukunft liegt
	 * und f�r keines der beiden Teams bereits ein anderes Spiel existiert.
	 * 
	 * PRE: Die Teams mit den uebergebenen IDs existieren bereits und sind nicht
	 * die gleichen.
	 * 
	 * @param team1ID
	 *            ID des ersten teilnehmenden Teams
	 * @param team2ID
	 *            ID des zweiten teilnehmenden Teams
	 * @param startzeit
	 *            Startzeitpunkt der Ansetzung
	 * @param mindesteinsatz
	 *            Mindesteinsatz in Euro
	 * 
	 * @return Im Erfolgsfall eine spielweit eindeutige ID
	 * 
	 * @throws RegretException
	 * 			Im Fehlerfall eine RegretException mit entsprechendem
	 *          Systemereignis {@link Systemereignis}
	 */
	public int spielEintragen(int t1id, int t2id, Calendar startzeit, int mindesteinsatz) throws RegretException {
		
		Calendar datum=BetAndRegret.getDatum();
		if(startzeit.before(datum)){
			throw new RegretException(Systemereignis.STARTZEIT_LIEGT_NICHT_IN_DER_ZUKUNFT);
		}
		Team t1 = teams.findeTeam(t1id);
		Team t2 = teams.findeTeam(t2id);
		Sportart sart1 = t1.getSportart();
		Sportart sart2 = t2.getSportart();
		if(sart1 != sart2){
			throw new RegretException(Systemereignis.SPORTARTEN_DER_TEAMS_VERSCHIEDEN);
		}
		int dauer = sart1.getSpieldauer();
		boolean t1_ok = t1.istFrei(startzeit, dauer);
		boolean t2_ok = t2.istFrei(startzeit, dauer);
		if(!t1_ok || !t2_ok){
			throw new RegretException(Systemereignis.TEAM_SPIELT_BEREITS);
		}
		
		Spiel s_neu = new Spiel(startzeit, sart1, t1, t2, mindesteinsatz);
		spiele.add(s_neu);
		t1.addSpiel(s_neu);
		t2.addSpiel(s_neu);
		wv.addSpiel(s_neu);
		
		return s_neu.getId();
	}

	public int sportartEintragen(String bezeichnung, int spieldauerInMinuten) {
		Sportart sportart = new Sportart(bezeichnung, spieldauerInMinuten);
		sportarten.add(sportart);
		return sportart.getId();
	}

	public Systemereignis ergebnisEintragen (int gewinnerTeamID, int spielID, String punktestand) 
		throws RegretException {
		
		Team gewinner = teams.findeTeam(gewinnerTeamID);
		
		//Team beteiligt?
		
		Spiel spiel = spiele.findeSpiel(spielID);
		Team gewinnerTeam = spiel.findeTeam(gewinnerTeamID);
		if (gewinnerTeam == null) {
			throw new RegretException(Systemereignis.TEAM_NICHT_BETEILIGT);
		}
		
		//Spiel beendet?

		Sportart sportart = gewinner.getSportart();
		int dauer = sportart.getSpieldauer();
		Calendar datum = BetAndRegret.getDatum();
		Calendar startzeit = spiel.getStartzeit();
		Calendar spielende = Spiel.getSpielende(startzeit, dauer);
		
		if (datum.before(spielende)) {
			throw new RegretException(Systemereignis.SPIEL_NOCH_NICHT_BEENDET);
		}
			
		//Ergebnis eintragen
	
		Endergebnis endergebnis = new Endergebnis(gewinner, punktestand);
		endergebnisse.addLast(endergebnis);
		
		//opt: Jemand darauf gewettet?
		
		WetteCollection wettcollection = spiel.getWetten();
		spiel.setEndergebnis(endergebnis);
		
		if (wettcollection.isEmpty()){
			return Systemereignis.ERGEBNIS_ERFOLGREICH_EINGETRAGEN;
		}
		else {
			return Systemereignis.ERGEBNIS_ERFOLGREICH_EINGETRAGEN_KUNDEN_INFORMIERT;
		}

	}

	public int teamEintragen(String teamName, int sportartID) {
		Sportart sportart = sportarten.findeSportart(sportartID);
		Team team = new Team(teamName, sportart);	    
		teams.add(team);
		sportart.addTeam(team);
		wv.addTeam(team);
		return team.getId();
	}

	public SportartCollection getSportarten() {
		return sportarten;
	}


	public SpielCollection getSpiele() {
		return spiele;
	}


	public String erstelleSpielplan() {
		
		StringBuilder sb = new StringBuilder();
		
		//erste Zeile mit Systemzeit
		Calendar datum = BetAndRegret.getDatum();
		
		String systemdatum = Time.formatToString(datum);

		sb.append("Spielplan [" + systemdatum +"]"  + '\n' + '\n'  );
		
		//Sportarten
		if(sportarten.isEmpty()==false){
			sb.append("Sportarten" + '\n'  );
			sb.append(sportarten.toString() + '\n'  );
		}
		//Spiele
		if(spiele.isEmpty()==false){
			sb.append("Spiele" + '\n'  );
			sb.append(spiele.toString());}
		
		return sb.toString();
	}

}
